﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using ExcelUtils;

/*
	Todo:
	Better values in width calculator.
	Headings
	font

*/
namespace DbView
{
	public partial class ExportExcelForm : Form
	{
		DataTable  GridData { get; set; }
		string TableName { get; set; }
		string OutputXlsFile { get {return textFileName.Text; } }
		bool wantOverrideTest;

		public ExportExcelForm(DataTable gridData, string table, string file, string database, string summary, string sql)
		{
			Initialise(gridData, table, file, database, summary, sql);
			wantOverrideTest = true; // test for file already existing unless name is selected from the save as dialog
			SetCSVControlState(false);
SetCSVControlState(true);
		}

		public void SetCSVControlState(bool show)
		{
			this.lblFormat.Visible = show;
			this.rFormatCSV.Visible = show;
			this.rFormatXLS.Visible = show;
		}

		void Initialise(DataTable gridData, string table, string file, string database, string summary, string sql)
		{
			InitializeComponent();
			GridData = gridData;
			TableName = table;
			textFileName.Text = file;

			lblHelp.Text = TITLE;
			lblGridData.Text = TableName;

			this.textCommand.Text = sql;
			this.textDatabase.Text = database;
			this.textSummary.Text = summary;

			comboHeader.Items.Add("Include Header");
			comboHeader.Items.Add("Header plus blank line");
			comboHeader.Items.Add("Data only; no Header");
			comboHeader.SelectedIndex = 0;
		}

		private void InitialiseFromView(ViewDefinition viewDef)
		{
		}


		private void ExportExcelForm_Load(object sender, EventArgs e) { SetupControls(); }

		private void SetupControls()
		{
			
		}
		
		private void button1_Click(object sender, EventArgs e) { this.Close(); }
		
		private void button2_Click(object sender, EventArgs e)
		{
			if (CheckConfirmOverride())
			{
				if (this.rFormatCSV.Checked)
					this.DoExportCSV(this.GridData, this.GetHeaderOption());
				else
					this.DoExport();
			}
		}


		private void btnBrowse_Click(object sender, EventArgs e)
		{
			textFileName.Text = GetFileName(textFileName.Text);
		}

		private void Format_CheckedChanged(object sender, EventArgs e)
		{
			RadioButton rb = sender as RadioButton;
			bool isCSV = (rb == this.rFormatCSV);
			this.SetSummaryState(!isCSV);
			textFileName.Text = this.AdjustFileExtention(textFileName.Text, isCSV);
		}

		private void SetSummaryState(bool enable)
		{
			this.groupBox1.Enabled = enable;
		}

		private string AdjustFileExtention(string fileName, bool isCSV)
		{
			string seek = (isCSV) ? ".XLS" : ".CSV";  // if CSV wanted search for XLS replace with CSV
			string repl = (isCSV) ? ".CSV" : ".XLS";  // if CSV wanted use CSV instead of XLS
			int ipos = fileName.ToUpper().LastIndexOf(seek);
			if (ipos > -1)
				fileName = fileName.Substring(0, ipos) + repl;
			return fileName;

		}

		private string GetFileName(String prevFileName)
		{
			SaveFileDialog createFileDialog = new SaveFileDialog();

			createFileDialog.FileName = Path.GetFileName(prevFileName);
			createFileDialog.Filter = this.MakeFilterText();
			createFileDialog.RestoreDirectory = true;

			if (createFileDialog.ShowDialog() == DialogResult.OK)
			{
				this.wantOverrideTest = false; // already been asked to confirm in the dialog
				return createFileDialog.FileName;

			}
			return prevFileName;
		}

		private string MakeFilterText()
		{
			if (this.rFormatCSV.Checked)
				return "CSV Files (*.csv)|*.csv";
			return "Excel XLS Files (*.xls)|*.xls";
		}

		private bool CheckConfirmOverride()
		{
			if (!wantOverrideTest) return true; // checked already. OK to go
			if (File.Exists(this.OutputXlsFile))
			{
				if (MessageBox.Show(String.Format("{0} exists and will be overwritten.\nProceed with export?", this.OutputXlsFile), 
									"Confirm continue", 
									MessageBoxButtons.YesNo,
									MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.No)
					return false; // brakes
			}
			return true;
		}
		
		private void DoExport()
		{
			//int headerSelection = this.comboHeader.SelectedIndex;
			//ExcelExporter.HeaderOption ho = (headerSelection == 0) ? ExcelExporter.HeaderOption.Header :
			//                                (headerSelection == 1) ? ExcelExporter.HeaderOption.HeaderAndSpace :
			//                                (headerSelection == 2) ? ExcelExporter.HeaderOption.None :
			//                                ExcelExporter.HeaderOption.Header;
			ExcelExporter.HeaderOption ho = this.GetHeaderOption();
			ExcelExporter builder = new ExcelExporter(OutputXlsFile, GridData, "Arial", 10);
			builder.Header = ho;
			AddSummaryInfo(builder);

			if (!builder.Export())
				MessageBox.Show(builder.LastError, "Error during export attempt", MessageBoxButtons.OK, MessageBoxIcon.Error);
			else
			{
				MessageBox.Show(String.Format("File {0}\nhas been created", OutputXlsFile), "Export completed", MessageBoxButtons.OK, MessageBoxIcon.Information);
				this.Close();
			}
		}

		private ExcelExporter.HeaderOption GetHeaderOption()
		{
			int headerSelection = this.comboHeader.SelectedIndex;
			ExcelExporter.HeaderOption ho = (headerSelection == 0) ? ExcelExporter.HeaderOption.Header :
											(headerSelection == 1) ? ExcelExporter.HeaderOption.HeaderAndSpace :
											(headerSelection == 2) ? ExcelExporter.HeaderOption.None :
											ExcelExporter.HeaderOption.Header;
			return ho;
		}

		private void AddSummaryInfo(ExcelExporter builder)
		{
			if (this.checkNoSummary.Checked == false)
			{
				AddSummaryItem(builder, this.textSummary, "Notes");
				AddSummaryItem(builder, this.textDatabase, "Database Source");
				AddSummaryItem(builder, this.textCommand, "SQL");
			}
		}

		private void AddSummaryItem(ExcelExporter builder, TextBox textBox, string itemTitle)
		{
			string value = textBox.Text;
			if (string.IsNullOrEmpty(value)) return;
			builder.AddSummaryItem(itemTitle, value);
		}

		private void DoExportCSV(DataTable dt, ExcelExporter.HeaderOption ho)
		{
			int headerSelection = this.comboHeader.SelectedIndex;
			try
			{
				StringWriter writer = new StringWriter();
				// TODO: the Unicode conundrum
				System.Text.Encoding fileEncoding = (false) ? System.Text.Encoding.Unicode : System.Text.Encoding.Default;
				TextWriter fileWriter = new StreamWriter(this.OutputXlsFile, false, fileEncoding);

				bool first = true;
				// write the header if required
				if (ho != ExcelExporter.HeaderOption.None)
				{
					foreach (DataColumn dc in dt.Columns)
					{
						if (!first) writer.Write(",");
						writer.Write(Csv.CsvWriter.CsvField(dc.ColumnName));
						if (first) first = false;
					}
					writer.Write("\n");
					first = true;
					if (ho == ExcelExporter.HeaderOption.HeaderAndSpace)
					{
						foreach (DataColumn dc in dt.Columns)
						{
							if (!first) writer.Write(",");
							writer.Write(Csv.CsvWriter.CsvField(""));
							if (first) first = false;
						}
						writer.Write("\n");
					}
				}
				foreach (DataRow dr in dt.Rows)
				{
					first = true;
					for (int idx = 0; idx < dt.Columns.Count; ++idx)
					{
						if (!first) writer.Write(",");
						writer.Write(Csv.CsvWriter.CsvField(dr[idx].ToString().TrimEnd()));
						if (first) first = false;
					}
					writer.Write("\n");
				}

				fileWriter.Write(writer.ToString());
				writer.Close();
				fileWriter.Close();
			
				MessageBox.Show(String.Format("File {0}\nhas been created", this.OutputXlsFile), "Export completed", MessageBoxButtons.OK, MessageBoxIcon.Information);
				this.Close();
			}
			catch (Exception exc)
			{
				MessageBox.Show(exc.Message, "Error during export attempt", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			finally
			{
			}
		}

		// help text for top of dialog.
		const string TITLE =
@"Export data from the current grid to Excel. Press [...] to change the default file name or location. XLS format is supported, but not XLSX. Press the Export button to create the file. Note: when data from a table is showing only the contents of the grid will be exported. To export a full table you must export to CSV.
";




	}
}
